package asteroids.model;

import asteroids.CollisionListener;
import be.kuleuven.cs.som.annotate.Basic;

/**
 * @version 0.3
 * @author  Tandan Sunil, Van Deun Luca
 */
public class Event {
	
	/**
	 * Creates a new Event with two given entities and given time left for this event to take place, representing a collision between two entities.
	 * 
	 * @param entity1 
	 * 		  The first given entity of the event.
	 * @param entity2
	 * 	      The second given entity of the event.
	 * @param time
	 * 		  The given time left for the event to take place.
	 * @pre	  The given entity1 must be a valid entity
	 * 		| Entity.isValidEntity(entity1)
	 * @pre	  The given entity2 must be a valid entity
	 * 		| Entity.isValidEntity(entity2)
	 * @pre   The given time is valid.
	 * 		| Entity.isValidDuration(time)
	 */
	public Event(Entity entity1,Entity entity2,double time){
		assert(Entity.isValidEntity(entity1) && Entity.isValidDuration(time) && Entity.isValidEntity(entity2)); 
		this.entity1=entity1;
		this.entity2= entity2;
		this.time= time;
	}
	
	/**
	 * Creates a new Event with a given entity and given time left for this event to take place, representing a collision between the given entity and a boundary of its current World.
	 * 
	 * @param entity1 
	 * 		  The first given entity of the event.
	 * @param time
	 * 		  The given time left for the event to take place.
	 * @pre	  The given entity1 must be a valid entity
	 * 		| Entity.isValidEntity(entity1)
	 * @pre   The given time is valid.
	 * 		| Entity.isValidDuration(time)
	 */
	public Event(Entity entity1,double time){
		assert(Entity.isValidEntity(entity1) && Entity.isValidDuration(time)); 
		this.entity1=entity1;
		this.entity2= null;
		this.time= time;
	}
	
	private Entity entity1,entity2;
	
	/**
	 *	Returns the first entity of this Event. 
	 */
	@Basic
	public Entity getEntity1() {
		return entity1;
	}
	
	/**
	 *	Returns the second entity of this Event, null in case of a collision with a boundary. 
	 */
	@Basic
	public Entity getEntity2() {
		return entity2;
	}

	/**
	 *	Returns the time left for the collision to take place.
	 */
	@Basic
	public double getTime() {
		return time;
	}

	private double time;
	
	/**
	 * Terminates this event.
	 * @post  ...
	 * 		| new.getEntity1()==null && new.getEntity2()==null && new.getTime()==Double.NaN
	 */
	public void terminate(){
		this.entity1=null;
		this.entity2=null;
		this.time=Double.NaN;
	}
	
	public void resolve(CollisionListener collisionListener){
		if(getEntity2()==null)
			getEntity1().collideWithBoundaries(collisionListener);
		else{
			//ref: error.png
			if(getEntity2().isTerminated()){
				getEntity1().die();
			}
			getEntity1().collide(getEntity2(),collisionListener);
			}
		
	}
	//////////////////////////////////////////////////////////////
//	public boolean contains(Entity e){
//		if(getEntity1()==e || getEntity2()==e)
//			return true;
//		return false;
//	}
//	
//	public void setTime(double time){
//		this.time=time;
//	}
//	
	
	
}
